/**
 * 
 */
package com.wilmar.process.core.services.api;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jbpm.api.task.Task;

import com.wilmar.common.util.PageinationEntity;
import com.wilmar.process.entity.InstanceOperateOpinion;
import com.wilmar.process.entity.Organization;
import com.wilmar.process.entity.Role;
import com.wilmar.process.entity.TaskInstanceProperties;
import com.wilmar.process.entity.User;
import com.wilmar.process.entity.query.ProcessTakenTaskQueryObject;
import com.wilmar.process.entity.query.ProcessUnassignTaskQueryObject;
import com.wilmar.process.entity.vo.TaskInstanceVO;
import com.wilmar.process.exception.ObjectNotFoundException;
import com.wilmar.process.exception.PermissionDeniedException;
import com.wilmar.process.exception.TaskAlreadyProcessedException;
import com.wilmar.process.exception.TaskAlreadyTakenByAnotherUserException;
import com.wilmar.process.exception.TaskRepeatAcceptedException;

/**
 * 系统任务服务接口
 * 
 * @author MaKuBEX E-mail:makubexnet@gmail.com
 * @version 1.0.0 at Aug 4, 2009 9:22:00 AM
 * 
 */
public interface ISystemTaskInstanceService extends
		IBaseService<TaskInstanceVO, Task> {
	/**
	 * 获取流程实例当前活动的节点
	 * 
	 * @param processInstanceId
	 *            流程实例编号
	 * @return 当前活动的节点
	 * @throws ObjectNotFoundException
	 *             如果当前流程实例编号对应的流程实例并不存在
	 */
	public List<Task> getCurrentActiveTaskInstanceList(String processInstanceId);

	/**
	 * 根据指定走向完成任务
	 * 
	 * @param taskInstanceId
	 *            任务实例编号
	 * @param outCome
	 *            任务走向
	 * @param user
	 *            用户
	 * @param opinion
	 *            处理意见
	 * @param variableMap
	 *            变量
	 * @param forceComplete
	 *            是否要强制完成任务，强制完成任务只有当任务没有被最终指派的情况下才有效
	 * @throws PermissionDeniedException
	 *             当完成用户并未被授权以完成当前任务
	 */
	public void completeTask(String taskInstanceId, String outCome, User user,
			InstanceOperateOpinion opinion, Map<String, ?> variableMap,
			boolean forceComplete) throws PermissionDeniedException;

	/**
	 * 完成任务
	 * 
	 * @param taskInstanceId
	 *            任务实例编号
	 * @param user
	 *            用户
	 * @param opinion
	 *            处理意见
	 * @param variableMap
	 *            变量
	 * @param forceComplete
	 *            是否要强制完成任务，强制完成任务只有当任务没有被最终指派的情况下才有效
	 * @throws PermissionDeniedException
	 *             当完成用户并未被授权以完成当前任务
	 */
	public void completeTask(String taskInstanceId, User user,
			InstanceOperateOpinion opinion, Map<String, ?> variableMap,
			boolean forceComplete) throws PermissionDeniedException;

	/**
	 * 根据用户获取该用户所有可参与且尚未被指派的任务实例集合，其中包含了用户所在机构与所在角色可参与的任务
	 * 
	 * @deprecated
	 * @param user
	 *            用户
	 * @param page
	 *            分页信息
	 * @return 任务实例集合
	 */
	public Set<Task> getListAllUnAssignedTaskInstanceByUser(User user,
			PageinationEntity page);

	/**
	 * 根据用户获取已经被指派任务实例集合
	 * 
	 * @deprecated
	 * @param user
	 *            用户
	 * @param page
	 *            分页信息
	 * @return 任务实例集合
	 */
	public List<Task> getListTakenTaskInstanceByUser(User user,
			PageinationEntity page);

	/**
	 * 根据机构获取尚未被指派任务实例集合
	 * 
	 * @param organization
	 *            机构实体集合
	 * @param page
	 *            分页信息
	 * @return 任务实例集合
	 */
	public Set<TaskInstanceVO> getListUnAssignedTaskInstanceByOrganization(
			Set<Organization> organizationSet, PageinationEntity page);

	/**
	 * 根据角色获取尚未被指派任务实例集合
	 * 
	 * @param role
	 *            角色实体
	 * @param page
	 *            分页信息
	 * @return 任务实例集合
	 */
	public Set<TaskInstanceVO> getListUnAssignedTaskInstanceByRole(
			Set<Role> roleSet, PageinationEntity page);

	/**
	 * 根据用户信息获取当前用户可以接收的任务实例数量
	 * 
	 * @param user
	 *            用户实体
	 * @return 可以接收的任务实例数量
	 */
	public Long getUnAssignedTaskInstanceCountByUser(User user);

	/**
	 * 根据用户信息获取该用户已经接收的任务实例数量
	 * 
	 * @param user
	 *            用户实体
	 * @return 已经接收的任务实例数量
	 */
	public Long getTakenTaskInstanceCountByUser(User user);

	/**
	 * 根据用户获取尚未被指派任务实例集合
	 * 
	 * @param user
	 *            用户
	 * @param page
	 *            分页信息
	 * @return 任务实例集合
	 */
	public Set<TaskInstanceVO> getListUnAssignedTaskInstanceByUser(
			Set<User> userSet, PageinationEntity page);

	/**
	 * 获取任务实例对应的表单地址
	 * 
	 * @param taskInstanceId
	 *            任务实例编号
	 * @return 表单地址
	 * @throws ObjectNotFoundException
	 *             当当前任务实例编号对应的任务实例不存在或者该任务实例已经过期
	 */
	public String getTaskForm(String taskInstanceId)
			throws ObjectNotFoundException;

	/**
	 * 获取任务,依次根据用户信息，用户所在角色，用户所属机构尝试获取该任务，只要其中任何一个条件满足即可成功获取该任务
	 * 
	 * @param taskInstanceId
	 *            任务实例编号
	 * @param user
	 *            用户
	 * @throws PermissionDeniedException
	 *             当接收用户并未被授权以接收当前任务
	 * @throws TaskRepeatAcceptedException
	 *             如果当前任务已经被当前的用户所接收
	 * @throws TaskAlreadyProcessedException
	 *             如果当前任务已经被处理过
	 * @throws ObjectNotFoundException
	 *             如果当前任务没有对应的流程实例
	 * @throws TaskAlreadyTakenByAnotherUserException
	 *             如果当前任务已经被其他用户所接收
	 */
	public void takeTask(String taskInstanceId, User user)
			throws PermissionDeniedException, TaskRepeatAcceptedException,
			TaskAlreadyProcessedException, ObjectNotFoundException,
			TaskAlreadyTakenByAnotherUserException;

	/**
	 * 弹出任务，只有任务的接收人才能拥有该操作
	 * 
	 * @param taskInstanceId
	 *            任务实例编号
	 * @param user
	 *            用户
	 * @throws PermissionDeniedException
	 *             当当前用户并不是任务的接收用户时
	 */
	public void popTask(String taskInstanceId, User user)
			throws PermissionDeniedException;

	/**
	 * 根据任务实例编号获取对应的流程实例中保存的数据
	 * 
	 * @param taskInstanceId
	 *            流程实例编号
	 * @return 流程实例中的数据
	 */
	public Map<String, ?> getDataByTaskInstanceId(String taskInstanceId);

	/**
	 * 根据任务实例编号获取当前任务结点被允许的流出流转名称
	 * 
	 * @param taskInstanceId
	 *            任务实例编号
	 * @return 流程流转名称集合
	 * @throws ObjectNotFoundException
	 *             如果任务实例没有被找到
	 */
	public Set<String> getOutComes(String taskInstanceId)
			throws ObjectNotFoundException;

	/**
	 * 根据用户和动态查询信息获取该用户所有可参与且尚未被指派的任务实例集合， 其中包含了用户所在机构与所在角色可参与的任务
	 * 
	 * @param user
	 *            用户
	 * @param queryObject
	 *            动态查询信息
	 * @return 任务实例集合
	 */
	public Set<Task> getListAllUnAssignedTaskInstanceByUser(User user,
			ProcessUnassignTaskQueryObject queryObject);

	/**
	 * 根据用户以及动态查询条件获取已经被指派任务实例集合
	 * 
	 * @param user
	 *            用户
	 * @param queryObject
	 *            查询对象
	 * @return 任务实例集合
	 */
	public List<Task> getListTakenTaskInstanceByUser(User user,
			ProcessTakenTaskQueryObject queryObject);

	/**
	 * 增加任务实例注释
	 * 
	 * @param taskInstanceId
	 *            任务实例编号
	 * @param comment
	 *            注释内容
	 * @param user
	 *            用户
	 * @param forceComment
	 *            是否强制增加注释
	 * @throws PermissionDeniedException
	 *             不强制增加注释并且当前任务并不属于该用户
	 */
	public void addComment(String taskInstanceId, String comment, User user,
			boolean forceComment) throws PermissionDeniedException;

	/**
	 * 怎加一条任务实例注释的回复信息
	 * 
	 * @param taskInstanceId
	 *            任务实例编号
	 * @param commentId
	 *            注释编号
	 * @param reply
	 *            回复信息
	 * @param user
	 *            回复人
	 */
	public void addCommentReply(String taskInstanceId, String commentId,
			String reply, User user);

	/**
	 * 根据任务实例编号获取任务实例实体
	 * 
	 * @param taskInstanceId
	 *            任务实例编号
	 * @return 任务实例实体
	 * @throws ObjectNotFoundException
	 *             当任务实例编号没有对应的任务实例实体时
	 */
	public Task getDetailById(String taskInstanceId)
			throws ObjectNotFoundException;

	/**
	 * 创建或者更新任务实例中的变量值
	 * 
	 * @param taskInstanceId
	 *            任务实例编号
	 * @param name
	 *            变量名称
	 * @param value
	 *            变量值
	 */
	public void createOrUpdateVariable(String taskInstanceId, String name,
			Object value);

	/**
	 * 创建或者更新任务实例中的变量值
	 * 
	 * @param taskInstanceId
	 *            任务实例编号
	 * @param variableMap
	 *            变量
	 */
	public void createOrUpdateVariables(String taskInstanceId,
			Map<String, ?> variableMap);

	/**
	 * 根据提供的任务实例编号以及变量的名称获取任务实例中对应变量的值
	 * 
	 * @param taskInstanceId
	 *            任务实例编号
	 * @param variableName
	 *            变量名称
	 * @return 流程变量对应的值
	 * @throws ObjectNotFoundException
	 *             如果任务实例中没有对应的变量
	 */
	public Object getVariable(String taskInstanceId, String variableName)
			throws ObjectNotFoundException;

	/**
	 * 根据提供的任务实例编号获取任务的描述信息
	 * 
	 * @param taskInstanceId
	 *            任务实例编号
	 * @return 任务实例对应的任务描述
	 * @throws ObjectNotFoundException
	 *             如果没有该任务实例
	 */
	public String getTaskDescription(String taskInstanceId)
			throws ObjectNotFoundException;

	public Task createSubTaskInstance(String parentTakeInstanceId,
			TaskInstanceProperties properties);
}
